﻿using System;

namespace EasyIot.WinApp
{
    /// <summary>
    /// 缓存数据类
    /// </summary>
    public class ByteBuffer
    {
        /// <summary>
        /// 缓冲区最大值
        /// </summary>
        const int BUFFERMAXSIZE = 1024 * 128;

        // 缓冲区数组
        private byte[] m_abyBuf; 

        /// <summary>
        /// 数组下标位置
        /// </summary>
        private int m_iPosition = 0;

        // 接收到的数据长度
        private int m_iRecvLength = 0;

        /// <summary>
        /// 是否等待继续接收
        /// </summary>
        private bool bWaitRecvRemain;

        public int Position
        {
            get { return m_iPosition; }
            set { m_iPosition = value; }
        }

        public int RecvLength
        {
            get { return m_iRecvLength; }
            set { m_iRecvLength = value; }
        }

        public bool WaitRecvRemain
        {
            get { return bWaitRecvRemain; }
            set { bWaitRecvRemain = value; }
        }

        public ByteBuffer()
        {
            m_abyBuf = new byte[BUFFERMAXSIZE]; 
        }

        public ByteBuffer(int bufferMaxSize)
        {
            m_abyBuf = new byte[bufferMaxSize]; 
        }

        /// <summary>
        /// 将数据压入缓冲数组
        /// </summary>
        /// <param name="_aby">源数组</param>
        /// <param name="_iOffset">起始位置</param>
        /// <param name="_iLength">长度</param>
        public void Put(byte[] _aby, int _iOffset, int _iLength)
        {
            // 溢出清理
            if (m_iRecvLength + _iLength >= BUFFERMAXSIZE)
            {
                Clear();
                return;
            }

            Array.Copy(_aby, _iOffset, m_abyBuf, m_iRecvLength, _iLength);
            m_iRecvLength += _iLength;
        }
        /// <summary>
        /// 获取单个字节数据
        /// </summary>
        /// <returns>byte</returns>
        public byte GetByte()
        {
            bWaitRecvRemain = false;
            if (m_iPosition + 1 > m_iRecvLength)
            {
                bWaitRecvRemain = true;
                return 0;
            }
            byte byRet = m_abyBuf[m_iPosition];
            m_iPosition++;

            return byRet;
        }
        /// <summary>
        /// 获取指定长度的字节数组
        /// </summary>
        /// <param name="Length">长度</param>
        /// <returns>byte[]</returns>
        public byte[] GetByteArray(int Length)
        {
            bWaitRecvRemain = false;
            if (m_iPosition + Length > m_iRecvLength)
            {
                bWaitRecvRemain = true;
                return null;
            }

            byte[] m_abyTmp = new byte[Length];

            Array.Copy(m_abyBuf, m_iPosition, m_abyTmp, 0, Length);

            m_iPosition += Length;

            return m_abyTmp;
        }

        public int GetPosition()
        {
            return m_iPosition;
        }

        public bool HasRemaining()
        {
            return m_iPosition < m_iRecvLength;
        }

        private int Remaining()
        {
            return m_iRecvLength - m_iPosition;
        }

        public void Clear()
        {
            m_iPosition = 0;
            m_iRecvLength = 0;
            bWaitRecvRemain = false;
            Array.Clear(m_abyBuf, 0, m_abyBuf.Length);
        }

        ~ByteBuffer()
        {
            Dispose(false);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
                GC.SuppressFinalize(this);
        }

        public void Dispose()
        {
            Dispose(true);
        }
    }
}
